package com.zlsy.springbootdemo.redis.bloom;

import com.google.common.base.Preconditions;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.util.Objects;

/**
 * @author zhouliang
 * @date 2021/1/26 14:03
 */
@Component
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class RedisBloomFilter {

  private final RedisTemplate<String, Serializable> redisTemplate;

  /** 根据给定的布隆过滤器添加值 */
  public <T> void addByBloomFilter(BloomFilterHelper<T> bloomFilterHelper, String key, T value) {
    Preconditions.checkArgument(bloomFilterHelper != null, "bloomFilterHelper不能为空");
    int[] offset = bloomFilterHelper.murmurHashOffset(value);
    for (int i : offset) {
      redisTemplate.opsForValue().setBit(key, i, true);
    }
  }

  /** 根据给定的布隆过滤器判断值是否存在 */
  public <T> boolean includeByBloomFilter(
      BloomFilterHelper<T> bloomFilterHelper, String key, T value) {
    Preconditions.checkArgument(bloomFilterHelper != null, "bloomFilterHelper不能为空");
    int[] offset = bloomFilterHelper.murmurHashOffset(value);
    for (int i : offset) {
      Boolean success = redisTemplate.opsForValue().getBit(key, i);
      if (Objects.isNull(success)) {
        return false;
      }
      if (Objects.equals(success, Boolean.FALSE)) {
        return false;
      }
    }
    return true;
  }
}
